package cliente;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.math.*;
import javax.swing.JFrame;
import javax.swing.JPanel;


public class Cliente2 extends JPanel implements Runnable{
	static final int RADIO = 20; 
	static final String HOST = "localhost"; 
	static final int PUERTO=4999; //puerto en el cual recibe el servidor
	Socket skCliente;             //socket mediante el cual me conecto al servidor 
	DataInputStream flujoEntrada; 
	DataOutputStream flujoSalida;
	
	
	int xActual; //coordenadas a las cuales camina el personaje
	int yActual;
	
	int xDeseada; //coordenadas a las cuales camina el personaje
	int yDeseada;
	
	double velocidad;
	double velocidadX;
	double velocidadY;
	double distanciaX;
	double distanciaY;
	
	double distancia;
	
	double angulo;
	
	public Cliente2(){		
		
		//para que la elipse que pinta no se vea la primera vez 
		xActual=0;
		yActual=0;
		xDeseada=0;
		yDeseada=0;
		
		velocidad=0.00015;
		distancia=0;
		distanciaX=0;
		distanciaY=0;
		angulo=0;
		
		addMouseListener(new mouseListener());

		//Establecer la conexion con el servidor
		try{		
			skCliente = new Socket( HOST , PUERTO );
			
			InputStream aux = skCliente.getInputStream();
			//genera el flujo de entrada, por aca RECIBO los mensajes que envie el servidor
			flujoEntrada = new DataInputStream( aux );
			
			OutputStream aux1 = skCliente.getOutputStream();
			//genera el flujo de salida, por aca se ENVIAN los menajes al servidor
			flujoSalida= new DataOutputStream( aux1 );
			
			//Creo un hilo que escuche los mensajes del servidor
			Runnable escuchaServidor = new HiloEscuchaServidor();
			Thread hilo = new Thread(escuchaServidor);
			hilo.start();	
			System.out.println("LLEGO UN CLIENTE");
			
			
			} catch( Exception e ) {
			
			System.out.println( e.getMessage() +"ERROR");
			
			}
		
		
		
		
	}
	
	@Override
	public void run() {
		double tiempo;
			try {
				while(true){
					tiempo = System.currentTimeMillis();
					Thread.sleep(20);
					tiempo=System.currentTimeMillis()-tiempo;
					actualizar(tiempo);
					repaint();
				}
				
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			
		
		
		
	}
	

	public void asignarPosicionDeseada(int x, int y) {
		xDeseada=x;
		yDeseada=y;
		calculaAngulo();
		distancia=0;
		distanciaX=0;
		distanciaY=0;
	}
	
	public void actualizar(double tiempo){
		
		if(xDeseada!=xActual || yDeseada!=yActual){
			
			distancia = distancia + (velocidad*tiempo);
			distanciaX= distanciaX+Math.cos(angulo)*distancia;
			distanciaY= distanciaY+Math.sin(angulo)*distancia;
			
			System.out.println("actualizo "+distanciaX+" "+distanciaY);
			
			//para las x
			if(xDeseada>xActual){
				xActual = xActual +((int) (distanciaX));
				if(xActual>xDeseada){
					xActual=xDeseada;
				}
			}else{
				if(xDeseada<xActual){
					xActual = xActual - ((int) (distanciaX));
					if(xActual<xDeseada){
						xActual=xDeseada;
					}
				}
			}
			//para las y
			if(yDeseada>yActual){
				yActual = yActual + ((int) (distanciaY));
				if(yActual>yDeseada){
					yActual=yDeseada;
				}
			}else{
				if(yDeseada<yActual){
					yActual = yActual - ((int) (distanciaY));
					if(yActual<yDeseada){
						yActual=yDeseada;
					}
				}
			}
		}
	}
	@Override
	public void paint(Graphics g) {
		g.clearRect(0, 0, 500, 500);
		
		g.setColor(Color.blue);
		String s = new String("HAZ CLICK ");
		g.drawString(s,10,10);
		
		g.setColor(Color.green);
		g.fillOval(xActual-(RADIO/2), yActual-(RADIO/2), RADIO, RADIO);
		g.setColor(Color.BLACK);
		g.drawOval(xActual-(RADIO/2), yActual-(RADIO/2), RADIO, RADIO);
		
		g.drawLine((xActual)+-5,(yActual), (xActual)+5, (yActual));
		g.drawLine((xActual), (yActual)-5, (xActual), (yActual)+5);
		
	}

	public void calculaAngulo(){
		int y =yDeseada-yActual;
		int x = xDeseada-xActual;
		if(x<0)
			x=x*-1;
		if(y<0)
			y=y*-1;
		angulo = Math.atan2(y,x);
	}
	private class HiloEscuchaServidor implements Runnable{
		int x,y;
		@Override
		public void run() {
			//escucho permanentemente los mensajes del servidor
			while(true){
				try {
					//Asumo que el servidor primero envia la coordenada X y luego la Y
					x=Integer.parseInt(flujoEntrada.readUTF());
					y=Integer.parseInt(flujoEntrada.readUTF());
					asignarPosicionDeseada(x, y);
					
					System.out.println("CLIENTE: X: "+xDeseada+" Y: "+yDeseada);
					//finalmete despues de haber recibio las coordenas vuelvo a pintarme con las nuevas corrdenadas
					repaint();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			
		}
		
	}

	private class mouseListener implements MouseListener{

		@Override
		public void mouseClicked(MouseEvent e) {
			//Cuando hacen click en mi obtengo donde me hicieron click me pinto de una vez
			// y envio el mensaje al servidor
		
			asignarPosicionDeseada(e.getX(),e.getY());
			
			try {
				//se envian las coordenadas  
				flujoSalida.writeUTF(""+xDeseada);
				flujoSalida.writeUTF(""+yDeseada);
				
				//tambien deberia enviar las actuales por cuestinoes de control
			
			} catch (IOException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}
			
		}


		@Override
		public void mouseEntered(MouseEvent e) {
			
			
		}

		@Override
		public void mouseExited(MouseEvent e) {
			// TODO Auto-generated method stub
			
		}

		@Override
		public void mousePressed(MouseEvent e) {
			// TODO Auto-generated method stub
			
		}

		@Override
		public void mouseReleased(MouseEvent e) {
			// TODO Auto-generated method stub
			
		}
		
	}
	
	
	
	
	public static void main( String[] arg ) {
		JFrame frame = new JFrame("Cliente 2");
		Cliente2 cliente = new Cliente2();
		frame.add(cliente);
		frame.setVisible(true);
		frame.setSize(300,300);
		cliente.grabFocus();
		Thread hilo = new Thread(cliente);
		hilo.start();
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
	}



	
	
}
